using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Transactions;

namespace Destra.Common.DataAccess
{
    public class TxScope : IDisposable
    {
        private TransactionScope m_transactionScope;
        private SqlConnection m_connection;
        private bool m_closeConnection;

        private const string c_appSettingKey = "TxScopeConnectionStringName";

        static TxScope()
        {
            if (ConfigurationManager.AppSettings[c_appSettingKey] == null)
            {
                throw new ApplicationException(
                    string.Format("You must specify the appSetting '{0}'", c_appSettingKey));
            }
        }

        public TxScope()
            : this(ConfigurationManager.AppSettings[c_appSettingKey])
        {

        }

        public TxScope(string connectionStringName) : this(new SqlConnection(ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString))
        {

        }

        public TxScope(SqlConnection connection)
        {
            m_transactionScope = new TransactionScope();
            m_connection = connection;
            if (m_connection.State != ConnectionState.Open)
            {
                m_connection.Open();
                m_closeConnection = true;
            }
            else
            {
                m_closeConnection = false;
            }
        }

        // IDisposable
        public void Dispose()
        {
            Dispose(true);

            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (m_closeConnection && (m_connection != null))
            {
                m_connection.Dispose();
                m_connection = null;
            }

            if (m_transactionScope != null)
            {
                m_transactionScope.Dispose();
                m_transactionScope = null;
            }
        }

        public void Complete()
        {
            m_transactionScope.Complete();
        }

        public SqlConnection Connection
        {
            get
            {
                return m_connection;
            }
        }
    }
}